﻿// Groupon.NET C# Library
// Copyright (c) 2011 James Paul Duncan (JPaulDuncan)
// The MIT License (MIT)
// Permission is hereby granted, free of charge, to any person obtaining a 
// copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included 
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE. 
// http://www.jpaulduncan.com

using System;
using System.Collections.Generic;

namespace Groupon.Net
{
    public sealed class Option : ModelBase
    {
        private string _buyUrl;
        private List<CustomField> _customFields;
        private string _externalUrl;
        private int _minimumPurchaseQuantity;
        private Price _price;
        private bool _isLimitedQuantity;
        private int _maximumPurchaseQuantity;
        private int _remainingQuantity;
        private bool _isSoldOut;
        private Price _value;
        private DateTime _expiresAt;
        private string _title;
        private Price _discount;
        private List<Detail> _details;
        private string _id;
        private int _discountPercentage;
        private int _soldQuantity;
        private int _initialQuantity;
        private List<Location> _redemptionLocations;

        public Option()
            : base()
        {
            _customFields = new List<CustomField>();
            _price = new Price();
            _value = new Price();
            _discount = new Price();
            _details = new List<Detail>();
            _redemptionLocations = new List<Location>();
        }

        public string BuyUrl
        {
            get { return _buyUrl; }
            set { base.SetProperty<string>("BuyUrl", ref _buyUrl, value); }
        }

        public string ExternalUrl
        {
            get { return _externalUrl; }
            set { base.SetProperty<string>("ExternalUrl", ref _externalUrl, value); }
        }

        public List<CustomField> CustomFields
        {
            get { return _customFields; }
            set { base.SetProperty<List<CustomField>>("CustomFields", ref _customFields, value); }
        }

        public int MinimumPurchaseQuantity
        {
            get { return _minimumPurchaseQuantity; }
            set { base.SetProperty<int>("MinimumPurchaseQuantity", ref _minimumPurchaseQuantity, value); }
        }
        
        public Price Price
        {
            get { return _price; }
            set { base.SetProperty<Price>("Price", ref _price, value); }
        }

        public bool IsLimitedQuantity
        {
            get { return _isLimitedQuantity; }
            set { base.SetProperty<bool>("IsLimitedQuantity", ref _isLimitedQuantity, value); }
        }

        public int MaximumPurchaseQuantity
        {
            get { return _maximumPurchaseQuantity; }
            set { base.SetProperty<int>("MaximumPurchaseQuantity", ref _maximumPurchaseQuantity, value); }
        }

        public int RemainingQuantity
        {
            get { return _remainingQuantity; }
            set { base.SetProperty<int>("RemainingQuantity", ref _remainingQuantity, value); }
        }

        public bool IsSoldOut
        {
            get { return _isSoldOut; }
            set { base.SetProperty<bool>("IsSoldOut", ref _isSoldOut, value); }
        }

        public Price Value
        {
            get { return _value; }
            set { base.SetProperty<Price>("Value", ref _value, value); }
        }
            

        public DateTime ExpiresAt
        {
            get { return _expiresAt; }
            set { base.SetProperty<DateTime>("ExpiresAt", ref _expiresAt, value); }
        }

        public string Title
        {
            get { return _title; }
            set { base.SetProperty<string>("Title", ref _title, value); }
        }

        public Price Discount
        {
            get { return _discount; }
            set { base.SetProperty<Price>("Discount", ref _discount, value); }
        }


        public List<Detail> Details
        {
            get { return _details; }
            set { base.SetProperty<List<Detail>>("Details", ref _details, value); }
        }

        public string Id
        {
            get { return _id; }
            set { base.SetProperty<string>("Id", ref _id, value); }
        }

        public int DiscountPercentage
        {
            get { return _discountPercentage; }
            set { base.SetProperty<int>("DiscountPercentage", ref _discountPercentage, value); }
        }

        public int SoldQuantity
        {
            get { return _soldQuantity; }
            set { base.SetProperty<int>("SoldQuantity", ref _soldQuantity, value); }
        }

        public int InitialQuantity
        {
            get { return _initialQuantity; }
            set { base.SetProperty<int>("InitialQuantity", ref _initialQuantity, value); }
        }

        public List<Location> RedemptionLocations
        {
            get { return _redemptionLocations; }
            set { base.SetProperty<List<Location>>("RedemptionLocations", ref _redemptionLocations, value); }
        }

        public static Option Parse(System.Xml.XmlNode xmlNode)
        {
            Option result = new Option();

            if (xmlNode != null)
            {
                result.BuyUrl = xmlNode.SelectSingleNode("buyUrl").GetText();

                foreach (System.Xml.XmlNode customFieldNode in xmlNode.SelectNodes(@"customFields/customField"))
                {
                    CustomField customField = CustomField.Parse(customFieldNode);
                    if (customField != null) { result.CustomFields.Add(customField); }
                }

                foreach (System.Xml.XmlNode detailNode in xmlNode.SelectNodes(@"details/detail"))
                {
                    Detail detail = Detail.Parse(detailNode);
                    if (detail != null) { result.Details.Add(detail); }
                }

                result.Discount = Price.Parse(xmlNode.SelectSingleNode("discount"));
                result.DiscountPercentage = xmlNode.SelectSingleNode("discountPercentage").GetInt();
                result.ExpiresAt = xmlNode.SelectSingleNode("expiresAt").GetDateTime();
                result.ExternalUrl = xmlNode.SelectSingleNode("externalUrl").GetText();
                result.Id = xmlNode.SelectSingleNode("id").GetText();
                result.InitialQuantity = xmlNode.SelectSingleNode("initialQuantity").GetInt();
                result.IsLimitedQuantity = xmlNode.SelectSingleNode("isLimitedQuantity").GetBool();
                result.IsSoldOut = xmlNode.SelectSingleNode("isSoldOut").GetBool();
                result.MaximumPurchaseQuantity = xmlNode.SelectSingleNode("maximumPurchaseQuantity").GetInt();
                result.MinimumPurchaseQuantity = xmlNode.SelectSingleNode("minimumPurchaseQuantity").GetInt();
                result.Price = Price.Parse(xmlNode.SelectSingleNode("price"));

                foreach (System.Xml.XmlNode redemptionLocationNode in xmlNode.SelectNodes(@"redemptionLocations/redemptionLocation"))
                {
                    Location location = Location.Parse(redemptionLocationNode);
                    if (location != null) { result.RedemptionLocations.Add(location); }
                }

                result.RemainingQuantity = xmlNode.SelectSingleNode("remainingQuantity").GetInt();
                result.SoldQuantity = xmlNode.SelectSingleNode("soldQuantity").GetInt();
                result.Title = xmlNode.SelectSingleNode("title").GetText();
                result.Value = Price.Parse(xmlNode.SelectSingleNode("value"));
                
            }    
                

            return result;
            }

    }
}
